package com.cashmama.market.api.domain.service;

import com.alibaba.fastjson.JSON;
import com.cashmama.market.api.domain.utils.AppUtils;
import com.cashmama.market.api.domain.vo.RequestLocalInfo;
import com.cashmama.market.api.domain.vo.user.profile.AccessTokenDTO;
import com.cashmama.market.api.domain.vo.user.profile.SocialBindMobileDTO;
import com.cashmama.market.api.domain.vo.user.profile.UserRegisterLoginVO;
import com.cashmama.market.api.infras.app.RequestBasicInfo;
import com.cashmama.market.api.infras.consts.RedisKeyConsts;
import com.cashmama.market.api.infras.enums.BasicErrorCodeEnum;
import com.cashmama.market.api.infras.enums.error.VerifyCodeErrorCodeEnum;
import com.cashmama.market.api.infras.enums.message.VerifyCodeTypeEnum;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.exception.common.ApiErrorException;
import com.fqgj.msg.enums.PushServicerTypeEnum;
import com.fqgj.xjd.user.client.enums.PlatformEnum;
import com.qianli.cashmama.product.facade.ProductFacade;
import com.qianli.cashmama.product.facade.result.ProductCategory;
import com.qianli.common.enums.BusinessTypeENUM;
import com.qianli.user.enums.ThirdPartLoginTypeEnum;
import com.qianli.user.facade.UserServiceFacade;
import com.qianli.user.ro.account.UserAccessRO;
import com.qianli.user.ro.account.UserProductCategoryRO;
import com.qianli.user.ro.account.UserThirdPartRO;
import com.qianli.user.ro.app.AppChannelRO;
import com.qianli.user.ro.app.AppInfoRO;
import com.qianli.user.ro.app.AppVersionRO;
import com.qianli.user.ro.app.PushRO;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @program: market-api
 * @description
 * @author: frank
 * @create: 2020-04-28 15:17
 **/
@Service
public class SocialService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SocialService.class);

    @Autowired
    private AppUtils appUtils;
    @Autowired
    private ProductFacade productFacade;
    @Autowired
    private UserServiceFacade userServiceFacade;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private UserEventTrackService userEventTrackService;

    /**
     * 社交网络三方账号绑定
     * @param accessTokenVO
     * @return
     */
    public UserRegisterLoginVO socialLogin(AccessTokenDTO accessTokenVO){

        UserThirdPartRO userThirdPartRO = new UserThirdPartRO();
        userThirdPartRO.setBiz(BusinessTypeENUM.XJD.getCode());
        userThirdPartRO.setAppCode(appUtils.getAppCode());
        //目前固定为facebook
        userThirdPartRO.setLoginTypeEnum(ThirdPartLoginTypeEnum.FACEBOOK);
        userThirdPartRO.setOpenId(accessTokenVO.getOpenId());

        Response<List<ProductCategory>> productCategoryListResponse = productFacade.getProductCategoryList(RequestLocalInfo.getRequestBasicInfo().getAppCode());
        List<ProductCategory> productCategoryList = productCategoryListResponse.getData();
        List<UserProductCategoryRO> userProductCategoryROList = new ArrayList<>();
        for (ProductCategory productCategory : productCategoryList) {
            UserProductCategoryRO userProductCategoryRO = new UserProductCategoryRO();
            userProductCategoryRO.setProductCategoryName(productCategory.getCode());
            userProductCategoryRO.setDailyRegisterUserLimit(productCategory.getCategoryConfig().getDailyOrganicRegisterUserLimit());
            userProductCategoryROList.add(userProductCategoryRO);
        }
        userThirdPartRO.setUserProductCategoryROList(userProductCategoryROList);

        userAppInfoInjection(userThirdPartRO, RequestLocalInfo.getRequestBasicInfo(), "");

        UserAccessRO userAccessRO = Optional.ofNullable(userServiceFacade.thirdSocialPartLogin(userThirdPartRO))
                .filter(Response::isSuccess)
                .map(Response::getData)
                .orElseThrow(() -> new ApiErrorException(BasicErrorCodeEnum.INTERNAL_SERVER_ERROR));
        UserRegisterLoginVO userRegisterLoginVO = new UserRegisterLoginVO()
                .setToken(userAccessRO.getAccessToken())
                .setMobile(userAccessRO.getMobile())
                .setUserCode(userAccessRO.getUserCode())
                .setCategoryCode(userAccessRO.getProductCategory())
                .setNewRegister(StringUtils.isEmpty(userAccessRO.getAccessToken()) ? true : false);
        return userRegisterLoginVO;
    }


    /**
     * 社交网络登录方式 绑定手机号
     *
     * @param socialBindMobileVO
     * @return
     */
    public UserRegisterLoginVO bindMobile(SocialBindMobileDTO socialBindMobileVO, String ip) {
        LOGGER.info("=== social bindMobile ===:request:{}", JSON.toJSONString(socialBindMobileVO));
        //校验验证码
        String redisVerifyCodeKey = RedisKeyConsts.VERIFY_CODE_REDIS_KEY_PREFIX + VerifyCodeTypeEnum.VERIFY_TYPE_LOGIN.getName() + socialBindMobileVO.getMobile();
        String redisVerifyCode = redisClient.get(redisVerifyCodeKey);
        if (!socialBindMobileVO.getVerifycode().equals(redisVerifyCode)) {
            throw new ApiErrorException(VerifyCodeErrorCodeEnum.VERIFYCODE_NOT_CORRECT);
        }
        UserThirdPartRO userThirdPartRO = new UserThirdPartRO();
        userThirdPartRO.setBiz(BusinessTypeENUM.XJD.getCode());
        userThirdPartRO.setAppCode(appUtils.getAppCode());
        //目前固定为facebook
        userThirdPartRO.setLoginTypeEnum(ThirdPartLoginTypeEnum.FACEBOOK);
        userThirdPartRO.setOpenId(socialBindMobileVO.getOpenId());
        userThirdPartRO.setMobile(socialBindMobileVO.getMobile());

        Response<List<ProductCategory>> productCategoryListResponse = productFacade.getProductCategoryList(RequestLocalInfo.getRequestBasicInfo().getAppCode());
        List<ProductCategory> productCategoryList = productCategoryListResponse.getData();
        List<UserProductCategoryRO> userProductCategoryROList = new ArrayList<>();
        for (ProductCategory productCategory : productCategoryList) {
            UserProductCategoryRO userProductCategoryRO = new UserProductCategoryRO();
            userProductCategoryRO.setProductCategoryName(productCategory.getCode());
            userProductCategoryRO.setDailyRegisterUserLimit(productCategory.getCategoryConfig().getDailyOrganicRegisterUserLimit());
            userProductCategoryROList.add(userProductCategoryRO);
        }
        userThirdPartRO.setUserProductCategoryROList(userProductCategoryROList);

        userAppInfoInjection(userThirdPartRO, RequestLocalInfo.getRequestBasicInfo(), ip);
        UserAccessRO userAccessRO = Optional.ofNullable(userServiceFacade.bindUserMobileBySocialOpenId(userThirdPartRO))
                .filter(Response::isSuccess)
                .map(Response::getData)
                .orElseThrow(() -> new ApiErrorException(BasicErrorCodeEnum.INTERNAL_SERVER_ERROR));
        UserRegisterLoginVO userRegisterLoginVO = new UserRegisterLoginVO()
                .setToken(userAccessRO.getAccessToken())
                .setMobile(userAccessRO.getMobile())
                .setUserCode(userAccessRO.getUserCode())
                .setCategoryCode(userAccessRO.getProductCategory())
                .setNewRegister(StringUtils.isEmpty(userAccessRO.getAccessToken()) ? true : false);
        userEventTrackService.e_app_register_success();
        return userRegisterLoginVO;
    }

    private void userAppInfoInjection(UserThirdPartRO userThirdPartRO, RequestBasicInfo requestBasicInfo, String ip) {
        if (null == requestBasicInfo) {
            return;
        }

        PlatformEnum platform = PlatformEnum.OTHER;
        if (StringUtils.isNotEmpty(requestBasicInfo.getAppClient())) {
            platform = PlatformEnum.getEnumByDesc(requestBasicInfo.getAppClient());
            platform = platform == null ? PlatformEnum.OTHER : platform;
        }
        String channelName = requestBasicInfo.getChannel();
        String guestId = requestBasicInfo.getGuestId();

        AppInfoRO appInfoRO = new AppInfoRO();

        AppChannelRO appChannelRO = new AppChannelRO();
        appChannelRO.setChannel(channelName);
        appChannelRO.setChannelId(0);
        appInfoRO.setChannel(appChannelRO);
        //TODO
        PushRO pushRO = new PushRO();
        pushRO.setPushId(requestBasicInfo.getClientId());
        pushRO.setType(PushServicerTypeEnum.FCM.getCode());
        appInfoRO.setPush(pushRO);

        AppVersionRO appVersionRO = new AppVersionRO();
        appVersionRO.setPlat(platform.getType());
        appVersionRO.setVersion(requestBasicInfo.getAppVersion());
        appVersionRO.setVersionCode(requestBasicInfo.getVersionCode() + "");
        appInfoRO.setVersion(appVersionRO);

        appInfoRO.setFrom(platform.getDesc());
        appInfoRO.setGuestId(guestId);
        appInfoRO.setIp(StringUtils.isNotEmpty(ip) ? ip : Strings.EMPTY);
        appInfoRO.setPackageName(requestBasicInfo.getPackageName());

        userThirdPartRO.setAppInfo(appInfoRO);
    }
}
